package com.jeejio.common.base.mvvm

import android.content.ComponentCallbacks
import android.content.Context
import android.content.res.Configuration
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import androidx.viewbinding.ViewBinding
import com.awesome.common.base.mvvm.BaseViewModel
import com.awesome.common.base.mvvm.ViewModelUtils
import com.awesome.common.util.ui.StatusBarUtil

/**
 * Author: JFangZ
 * Email:  janezhang1901@163.com
 * Date:2021/5/19 10:54
 * Description:The base of activity.If want to use MVVM frame,please inherit this.
 */
abstract class BaseMVVMActivity<VM : BaseViewModel<*>, VB : ViewBinding> : AppCompatActivity() {
    protected var rootView: View? = null

    private var density = 0f
    private var scaledDensity = 0f

    protected val viewModel: VM by lazy { ViewModelUtils.createViewModel<VM>(this, 0) }
    protected val viewBinding: VB by lazy { ViewModelUtils.createViewBinding(this, 1)!! }

    /**
     * 返回ID或者View 如果使用ViewBinding 返回null或者不实现
     */
    open fun initLayout(): Any? = null

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:32
     * Description:Do UI init operation,such as findViewByID,setAdapter and so on.
     */
    open fun initView() {}

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:32
     * Description:Do setListener/setCallback operation.
     */
    open fun initListener() {}

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:32
     * Description:Do init observer of live data.
     */
    open fun initObserver() {}

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2019/4/8 11:34
     * Description:Do data init operation,such as network request,read database,read file and so on.
     */
    open fun initData() {}

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (immersive() == true) {
            // 使内容延伸到状态栏下
            StatusBarUtil.setStatusBarTranslucent(window, true)
            // 使状态栏透明
            StatusBarUtil.setStatusBarColor(window, Color.TRANSPARENT, false)
        } else if (immersive() == false) {
            StatusBarUtil.setStatusBarTranslucent(window, false)
        }
        // 状态栏背景颜色
        initStatusBarColor()?.let {
            StatusBarUtil.setStatusBarColor(window, it, false)
            // 根据状态栏颜色自动切换状态栏文字的颜色
            StatusBarUtil.setAutoStatusBarStyle(window)
        }
        // 状态栏深色图标
        initStatusBarDark()?.let { StatusBarUtil.setStatusBarStyle(window, it) }
        // 导航栏颜色
        initNavigationBarColor()?.also {
            window.navigationBarColor = it
        }
        setCustomDensity()
        when (val view = initLayout()) {
            is View -> {
                rootView = view; setContentView(rootView)
            }
            is Int -> {
                rootView = layoutInflater.inflate(view, null)
                setContentView(rootView)
            }
            else -> {
                rootView = viewBinding.root
                setContentView(rootView)
            }
        }
        initView()
        initListener()
        initObserver()
        initData()
    }

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date: 2021/8/22 22:49
     * Description:屏幕适配
     */
    protected open fun setCustomDensity() {
        val displayMetrics = application.resources.displayMetrics
        if (density == 0f) {
            density = displayMetrics.density
            scaledDensity = displayMetrics.scaledDensity
            // 监听切换字体
            application.registerComponentCallbacks(object : ComponentCallbacks {
                override fun onConfigurationChanged(newConfig: Configuration) {
                    if (newConfig.fontScale > 0) {
                        scaledDensity = application.resources.displayMetrics.scaledDensity
                    }
                }

                override fun onLowMemory() {}
            })
        }
        // 以 360dp 的设计图为标准
        val targetDensity = (displayMetrics.widthPixels / 360).toFloat()
        val targetScaledDensity = targetDensity * (scaledDensity / density)
        val targetDensityDpi = (160 * targetDensity).toInt()
        displayMetrics.density = targetDensity
        displayMetrics.scaledDensity = targetScaledDensity
        displayMetrics.densityDpi = targetDensityDpi
        val activityDisplayMetrics = resources.displayMetrics
        activityDisplayMetrics.density = targetDensity
        activityDisplayMetrics.scaledDensity = targetScaledDensity
        activityDisplayMetrics.densityDpi = targetDensityDpi
    }

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:39
     * Description:Make the activity immersive or not,if enable immersion,the status bar will transparent.
     *
     * @return Returns true to enable immersion,false not to enable immersion.
     */
    protected open fun immersive(): Boolean? = null

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:44
     * Description:Set the color of status bar.
     *
     * @return Color's value.
     */
    protected open fun initStatusBarColor(): Int? = null

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:45
     * Description:Set the mode of icon in status bar
     *
     * @return Returns true to start dark mode,false to start light mode.
     */
    protected open fun initStatusBarDark(): Boolean? = null

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2021/4/8 11:44
     * Description:Set the color of navigation bar.
     *
     * @return Color's value.
     */
    protected open fun initNavigationBarColor(): Int? = null

    protected fun getContext(): Context = this

    protected fun getActivity(): FragmentActivity = this

    protected open fun toastShort(content: String?) =
        Toast.makeText(this, content, Toast.LENGTH_SHORT).show()

    protected open fun toastLong(content: String?) =
        Toast.makeText(this, content, Toast.LENGTH_LONG).show()

}